#include "Semaphore.h"

namespace Lame3d
{
	Semaphore::Semaphore(int initCount)
			: sdlSem(NULL)
	{
		sdlSem = SDL_CreateSemaphore(initCount);
		if(!sdlSem) {
			throw "Failed to create SDL semaphore.";
		}
	}
	
	Semaphore::~Semaphore()
	{
		SDL_DestroySemaphore(sdlSem);
	}
	
	Semaphore::Lock::Lock(Semaphore &s, bool v)
			: sem(s), valid(v)
	{
	}
	
	Semaphore::Lock::~Lock()
	{
		if(valid) {
			if(SDL_SemPost(sem.sdlSem)==-1) {
				throw "Failed to post SDL semaphore.";
			}
		}
	}
	
	bool Semaphore::Lock::operator*() const
	{
		return valid;
	}
	
	Semaphore::Lock Semaphore::Wait(int timeout)
	{
		if(timeout < 0) {
			if(SDL_SemWait(sdlSem) == -1) {
				throw "Error in SDL_SemWait";
			}
			return Lock(*this, true);
		} else if(timeout == 0) {
			int val = SDL_SemTryWait(sdlSem);
			if(val == -1) {
				throw "Error in SDL_SemTryWait";
			}
			return Lock(*this, val==0);
		} else {
			Uint32 utime = timeout;
			int val = SDL_SemWaitTimeout(sdlSem, utime);
			if(val == -1) {
				throw "Error in SDL_SemWaitTimeout";
			}
			return Lock(*this, val==0);
		} 
	}
}
